package com.fudan.adse.service.impl;

import com.fudan.adse.domain.cont.OrderStatus;
import com.fudan.adse.domain.cont.TopUpType;
import com.fudan.adse.domain.dto.NewTopUpDTO;
import com.fudan.adse.domain.po.*;
import com.fudan.adse.exception.ApiException;
import com.fudan.adse.mbg.mapper.TopUpOrderMapper;
import com.fudan.adse.service.TopUpService;
import com.fudan.adse.service.WalletService;
import com.fudan.adse.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static com.fudan.adse.api.ResultCode.FAILED;

@Slf4j
@Service
public class TopUpServiceImpl implements TopUpService {
    @Autowired
    private TopUpOrderMapper topUpOrderMapper;
    @Autowired
    private WalletService walletService;

    @Override
    public List<TopUpOrder> getOrdersByConditions(String username, String status) {
        TopUpOrderExample example = new TopUpOrderExample();
        TopUpOrderExample.Criteria criteria = example.createCriteria();
        if (!ObjectUtils.isEmpty(username)) {
            criteria.andUsernameEqualTo(username);
        }
        if (status != null) {
            if (Arrays.stream(OrderStatus.values()).anyMatch(s -> s.getStatus().equals(status))) {
                criteria.andStatusEqualTo(status);
            } else {
                throw new ApiException("订单状态不存在");
            }
        }
        return topUpOrderMapper.selectByExample(example);
    }

    @Override
    public TopUpOrder topUp(NewTopUpDTO newTopUp) {
        if (Arrays.stream(TopUpType.values()).noneMatch(s -> s.getType().equals(newTopUp.getType()))) {
            throw new ApiException("充值类型不存在");
        }
        log.info("开始充值");
        TopUpOrder order = new TopUpOrder();
        BeanUtils.copyProperties(newTopUp, order);
        order.setUuid(UUIDUtil.generateUUID(newTopUp.toString()));
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        order.setStatus(OrderStatus.UNPAID.getStatus());
        if (topUpOrderMapper.insert(order) > 0) {
            log.warn("充值失败");
            return order;
        }
        throw new ApiException(FAILED);
    }

    @Override
    public void updateOrder(String uuid, String status) {
        TopUpOrder order = new TopUpOrder();
        if (status != null && Arrays.stream(OrderStatus.values()).noneMatch(s -> s.getStatus().equals(status))) {
            throw new ApiException("订单状态不存在");
        } else {
            order.setStatus(status);
        }
        TopUpOrder old = getOrderByUuid(uuid);
        order.setId(old.getId());
        order.setUpdateTime(new Date());
        log.info("更新钱包");
        if (topUpOrderMapper.updateByPrimaryKeySelective(order) > 0) {
            if (OrderStatus.PAID.getStatus().equals(status)) {
                Wallet wallet = walletService.getWalletByUsername(old.getUsername());
                // 更新钱包
                if (OrderStatus.UNPAID.getStatus().equals(old.getStatus()) &&
                        OrderStatus.PAID.getStatus().equals(status)) {
                    // 增加收入
                    log.info("计入收入");
                    wallet.setIncome(wallet.getIncome().add(old.getAmounts()));
                }
                // 更新余额：收 - 支
                log.info("更新余额");
                wallet.setBalance(wallet.getIncome().subtract(wallet.getOutcome()));
                if (walletService.updateByPrimaryKeySelective(wallet) <= 0) {
                    log.warn("更新失败");
                    throw new ApiException(FAILED);
                }
            }
            return;
        }
        throw new ApiException(FAILED);
    }

    private TopUpOrder getOrderByUuid(String uuid) {
        TopUpOrderExample example = new TopUpOrderExample();
        example.createCriteria().andUuidEqualTo(uuid);
        List<TopUpOrder> orders = topUpOrderMapper.selectByExample(example);
        if (orders.isEmpty()) {
            throw new ApiException("充值订单不存在");
        }
        return orders.get(0);
    }
}
